﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using InternshipManagement.Models;
using InternshipManagement.Helpers;
using System.Web.Security;

namespace InternshipManagement.Controllers
{
    public class AccountController : Controller
    {

        AccountRepository accountRepository = new AccountRepository();
        SemesterRepository semesterRepository = new SemesterRepository();
        CourseRepository courseRepository = new CourseRepository();
        // **************************************
        // URL: /Account/LogOn
        // **************************************

        public ActionResult LogOn()
        {
            return View();
        }

        [HttpPost]
        public ActionResult LogOn(LogOnModel model, string returnURL)
        {
            if (ModelState.IsValid)
            {
                if (accountRepository.ValidateUser(model.UserName, model.Password))
                {
                    User user = accountRepository.GetUser(model.UserName);
                    if (user.UserType.UserTypeName.Equals("Supervisor"))
                    {
                        Supervisor supervisor = user.Supervisor;
                        Session["DisplayName"] = supervisor.Name + supervisor.Surname;
                        Session["UserTypeID"] = user.UserTypeID;
                        Session["UserType"] = "Supervisor";
                        Session["Role"] = SiteRoles.Supervisor;
                    }
                    else if (user.UserType.UserTypeName.Equals("Student"))
                    {
                        Student student = user.Student;
                        Session["DisplayName"] = student.Name + student.Surname;
                        Session["UserTypeID"] = user.UserTypeID;
                        Session["UserType"] = "Student";
                        Session["Role"] = SiteRoles.Student;
                    }
                    else if (user.UserType.UserTypeName.Equals("Company"))
                    {
                        Company company = accountRepository.GetCompany(user.UserName);
                        Session["DisplayName"] = company.Name;
                        Session["UserTypeID"] = user.UserTypeID;
                        Session["UserType"] = "Company";
                        Session["Role"] = SiteRoles.Company;
                    }
                    else if (user.UserType.UserTypeName.Equals("Secretary"))
                    {
                        Secretary secretary = user.Secretary;
                        Session["DisplayName"] = secretary.Name + secretary.Surname;
                        Session["UserTypeID"] = user.UserTypeID;
                        Session["UserType"] = "Secretary";
                        Session["Role"] = SiteRoles.Secretary;
                    }
                    Session["UserID"] = user.ID;
                    Session["ActiveInternshipSemester"] = semesterRepository.GetActiveSemester().DisplayName;
                    Session["UserPrivileges"] = accountRepository.FindAllUserPrivilegesIDs(user.UserTypeID);
                    FormsAuthentication.SetAuthCookie(model.UserName, false);



                    if (returnURL != null && returnURL != "/")
                    {
                        Response.Redirect(returnURL);
                    }
                    return RedirectToAction("Index", "Announcement");
                }
                else
                {
                    ModelState.AddModelError("", "The user name or password provided is incorrect.");
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        // **************************************
        // URL: /Account/ForgotPassword
        // **************************************

        public ActionResult ForgotPassword()
        {
            return View();
        }

        [HttpPost]
        public ActionResult ForgotPassword(PasswordModel model)
        {
            if (ModelState.IsValid)
            {
                if (accountRepository.UserExists(model.UserName))
                {
                    string randomPassword = System.IO.Path.GetRandomFileName().Replace(".", "");
                    if (EmailSender.sendMail(model.UserName,
                                            "CTIS IMS Account Information",
                                            "You account details are as below\nUser Name : " + model.UserName + "\nPassword : " + randomPassword))
                    {
                        User user = accountRepository.GetUser(model.UserName);
                        user.Password = randomPassword;
                        accountRepository.Save();
                        return RedirectToAction("PasswordSend");
                    }
                    else
                    {
                        ModelState.AddModelError("", "An error occured while sending an email.");
                    }
                }
                else
                {
                    ModelState.AddModelError("", "The user name provided is incorrect.");
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        public ActionResult PasswordSend()
        {
            return View();
        }

        // **************************************
        // URL: /Account/LogOff
        // **************************************

        public ActionResult LogOff()
        {
            Session.Clear();
            FormsAuthentication.SignOut();

            return RedirectToAction("Logon", "Account");
        }



        [CustomAuthorize(Privileges = UserPrivileges.CreateUser)]
        public ActionResult UserCreate()
        {
            ViewBag.Op = "Create";
            return View("UserCreateEdit");
        }
        [HttpPost]
        [CustomAuthorize(Privileges = UserPrivileges.CreateUser)]
        public ActionResult UserCreate(UserModel usermodel)
        {
            if (ModelState.IsValid)
            {
                if (!accountRepository.UserExists(usermodel.UserName))
                {
                    if (usermodel.UserName.Contains('@'))
                    {
                        string randomPassword = System.IO.Path.GetRandomFileName().Replace(".", "");
                        if (EmailSender.sendMail(usermodel.UserName,
                                                "CTIS IMS Account Information",
                                                "You account details are as below\nUser Name : " + usermodel.UserName + "\nPassword : " + randomPassword))
                        {
                            User user = new User();
                            user.UserName = usermodel.UserName;
                            user.Password = randomPassword;
                            user.UserTypeID = accountRepository.GetUserTypeID(usermodel.UserType);
                            accountRepository.AddUser(user);
                            if (usermodel.UserType == "Supervisor" || usermodel.UserType == "Secretary")
                            {
                                if (usermodel.UserType == "Supervisor")
                                {
                                    Supervisor supervisor = new Supervisor();
                                    supervisor.Name = usermodel.Name;
                                    supervisor.Surname = usermodel.Surname;
                                    accountRepository.AddSupervisor(supervisor);
                                }
                                else if (usermodel.UserType == "Secretary")
                                {
                                    Secretary secretary = new Secretary();
                                    secretary.Name = usermodel.Name;
                                    secretary.Surname = usermodel.Surname;
                                    accountRepository.AddSecretary(secretary);
                                }
                                accountRepository.Save();

                                return RedirectToAction("UserList");
                            }
                            else
                            {
                                ModelState.AddModelError("", "User type must be selected from dropdown menu.");
                            }
                        }
                        else
                        {
                            ModelState.AddModelError("", "An error occured while sending an email.");
                        }
                    }
                    else
                    {
                        ModelState.AddModelError("UserName", "User Name field must be an e-mail address.");
                    }
                }
                else
                {
                    ModelState.AddModelError("", "The user name already exists.");
                }
            }
            ViewBag.Op = "Create";
            return View("UserCreateEdit", usermodel);
        }

        [CustomAuthorize(Privileges = UserPrivileges.EditUser)]
        public ActionResult UserEdit(int id)
        {
            User user = accountRepository.GetUserByID(id);
            if (user == null || (user.UserType.UserTypeName != "Supervisor" && user.UserType.UserTypeName != "Secretary"))
                return View("ShowMessage", "User does not exists");
            ViewBag.Op = "Edit";
            UserModel model = new UserModel();
            model.UserName = user.UserName;
            model.Name = user.UserType.UserTypeName == "Supervisor" ? user.Supervisor.Name : user.Secretary.Name;
            model.Surname = user.UserType.UserTypeName == "Supervisor" ? user.Supervisor.Surname : user.Secretary.Surname;
            model.UserType = user.UserType.UserTypeName;
            ViewBag.Op = "Edit";
            return View("UserCreateEdit", model);
        }
        [HttpPost]
        [CustomAuthorize(Privileges = UserPrivileges.EditUser)]
        public ActionResult UserEdit(int id, UserModel usermodel)
        {
            User user = accountRepository.GetUserByID(id);
            if (user == null || (user.UserType.UserTypeName != "Supervisor" && user.UserType.UserTypeName != "Secretary"))
                return View("ShowMessage", "User does not exists");
            user.UserTypeID = accountRepository.GetUserTypeID(usermodel.UserType);
            if (ModelState.IsValid)
            {
                if (usermodel.UserType == "Supervisor" || usermodel.UserType == "Secretary")
                {
                    if (usermodel.UserType == "Supervisor")
                    {
                        user.Supervisor.Name = usermodel.Name;
                        user.Supervisor.Surname = usermodel.Surname;
                    }
                    else if (usermodel.UserType == "Secretary")
                    {
                        user.Secretary.Name = usermodel.Name;
                        user.Secretary.Surname = usermodel.Surname;
                    }
                    accountRepository.Save();

                    return RedirectToAction("UserList");
                }
                else
                {
                    ModelState.AddModelError("", "User type must be selected from dropdown menu.");
                }
            }
            ViewBag.Op = "Edit";
            return View("UserCreateEdit", usermodel);
        }

        // **************************************
        // URL: /Account/UserList/
        // **************************************
        [CustomAuthorize(Privileges = UserPrivileges.ListUsers)]
        public ActionResult UserList(int? page)
        {
            const int pageSize = 10;

            IQueryable<User> users = null;

            users = accountRepository.FindAllSupervisorSecretary();

            var paginatedStudents = new PaginatedList<User>(users, page ?? 0, pageSize);

            return View(paginatedStudents);
        }
        
        // **************************************
        // URL: /Account/StudentList/
        // **************************************
        [CustomAuthorize(Privileges = UserPrivileges.DeleteUser)]
        public ActionResult UserDelete(int id)
        {
            User user = accountRepository.GetUserByID(id);
            if (user == null || (user.UserType.UserTypeName != "Supervisor" && user.UserType.UserTypeName != "Secretary"))
                return View("ShowMessage", "User does not exists");
            if (user.UserType.UserTypeName == "Supervisor")
            {
                Supervisor supervisor = accountRepository.GetSupervisor(user.ID);
                accountRepository.DeleteSupervisor(supervisor);
                accountRepository.DeleteUser(user);
            }
            else if (user.UserType.UserTypeName == "Supervisor")
            {
                Secretary secretary = accountRepository.GetSecretary(user.ID);
                accountRepository.DeleteSecretary(secretary);
                accountRepository.DeleteUser(user);
            }
            accountRepository.Save();
            return RedirectToAction("StudentList");
        }

        
        #region Student
        // **************************************
        // URL: /Account/StudentCreateEdit/Id/
        // **************************************
        [CustomAuthorize(Privileges = UserPrivileges.CreateStudent)]
        public ActionResult StudentCreate()
        {
            ViewBag.Op = "Create";
            ViewBag.Courses = courseRepository.FindAllActiveCourses().ToList();
            return View("StudentCreateEdit");
        }
        [HttpPost]
        [CustomAuthorize(Privileges = UserPrivileges.CreateStudent)]
        public ActionResult StudentCreate(Student student)
        {
            if (ModelState.IsValid)
            {
                if (!accountRepository.UserExists(student.UserName))
                {

                    string randomPassword = System.IO.Path.GetRandomFileName().Replace(".", "");
                    if (EmailSender.sendMail(student.Email,
                                            "CTIS IMS Account Information",
                                            "You account details are as below\nUser Name : " + student.UserName + "\nPassword : " + randomPassword))
                    {
                        User user = new User();
                        user.UserName = student.UserName;
                        user.Password = randomPassword;
                        user.UserTypeID = accountRepository.GetUserTypeID("Student");

                        accountRepository.AddUser(user);
                        accountRepository.AddStudent(student);
                        accountRepository.Save();

                        return RedirectToAction("StudentList");
                    }
                    else
                    {
                        ModelState.AddModelError("", "An error occured while sending an email.");
                    }
                }
                else
                {
                    ModelState.AddModelError("", "The user name already exists.");
                }
            }
            ViewBag.Op = "Create";
            ViewBag.Courses = courseRepository.FindAllActiveCourses().ToList();
            return View("StudentCreateEdit", student);
        }

        [CustomAuthorize(Privileges = UserPrivileges.EditStudent)]
        public ActionResult StudentEdit(int id)
        {
            Student student = accountRepository.GetStudent(id);
            if (student == null)
                return View("ShowMessage", "Student does now exists");
            ViewBag.Op = "Edit";
            ViewBag.Courses = courseRepository.FindAllActiveCourses().ToList();
            return View("StudentCreateEdit", student);
        }
        [HttpPost]
        [CustomAuthorize(Privileges = UserPrivileges.EditStudent)]
        public ActionResult StudentEdit(int id, FormCollection formvalues)
        {
            Student student = accountRepository.GetStudent(id);
            if (student == null)
                return View("ShowMessage", "Student does now exists");
            if (TryUpdateModel(student, formvalues))
            {
                accountRepository.Save();
                return RedirectToAction("StudentList");
            }
            ViewBag.Op = "Edit";
            ViewBag.Courses = courseRepository.FindAllActiveCourses().ToList();
            return View("StudentCreateEdit", student);
        }

        // **************************************
        // URL: /Account/StudentList/
        // **************************************
        [CustomAuthorize(Privileges = UserPrivileges.ListStudents)]
        public ActionResult StudentList(int? page)
        {
            const int pageSize = 10;

            IQueryable<Student> students = null;

            students = accountRepository.FindAllStudents();

            var paginatedStudents = new PaginatedList<Student>(students, page ?? 0, pageSize);

            return View(paginatedStudents);
        }

        // **************************************
        // URL: /Account/StudentList/
        // **************************************
        [CustomAuthorize(Privileges = UserPrivileges.DeleteStudent)]
        public ActionResult StudentDelete(int id)
        {
            Student student = accountRepository.GetStudent(id);
            accountRepository.DeleteStudent(student);
            User user = accountRepository.GetUserByID(id);
            accountRepository.DeleteUser(user);
            accountRepository.Save();
            return RedirectToAction("StudentList");
        }
        #endregion


        [CustomAuthorize(Privileges = UserPrivileges.CalendarManagement)]
        public JsonResult FindStudentsByCourseID(int CourseID)
        {
            return Json(accountRepository.FindAllStudents(CourseID).Select(s => new { s.ID, DisplayName = s.Name + " " + s.Surname }).ToList(), JsonRequestBehavior.AllowGet);
        }

        #region Company,
        // **************************************
        // URL: /Account/CompanyCreateEdit/Id/
        // **************************************
        //[CustomAuthorize(Privileges = UserPrivileges.CreateCompany)]
        public ActionResult CompanyCreate()
        {
            ViewBag.Op = "Create";
            ViewBag.Courses = courseRepository.FindAllActiveCourses().ToList();
            return View("CompanyCreateEdit");
        }

        [HttpPost]
        //[CustomAuthorize(Privileges = UserPrivileges.CreateCompany)]
        public ActionResult CompanyCreate(Company company)
        {
            if (ModelState.IsValid)
            {
                if (!accountRepository.UserExists(company.UserName))
                {

                    string randomPassword = System.IO.Path.GetRandomFileName().Replace(".", "");
                    /*if (EmailSender.sendMail(company.UserName,
                                            "CTIS IMS Account Information",
                                            "You account details are as below\nUser Name : " + company.UserName + "\nPassword : " + randomPassword))
                    {*/
                        User user = new User();
                        user.UserName = company.UserName;
                        user.Password = randomPassword;
                        user.UserTypeID = accountRepository.GetUserTypeID("Company");

                        accountRepository.AddUser(user);
                        accountRepository.Save();
                        company.ID = user.ID;
                        accountRepository.AddCompany(company);
                        accountRepository.Save();

                        return RedirectToAction("CompanyList");
                   /* }
                    else
                    {
                        ModelState.AddModelError("", "An error occured while sending an email.");
                    }*/
                }
                else
                {
                    ModelState.AddModelError("", "The user name already exists.");
                }
            }
            ViewBag.Op = "Create";
            return View("CompanyCreateEdit", company);
        }

        //[CustomAuthorize(Privileges = UserPrivileges.EditCompany)]
        public ActionResult CompanyEdit(int id)
        {
            Company company = accountRepository.GetCompany(id);
              
            if (company == null)
                return View("ShowMessage", "Company does not exists");
            ViewBag.Op = "Edit";
            return View("CompanyCreateEdit", company);
        }
       
        [HttpPost]
        //[CustomAuthorize(Privileges = UserPrivileges.EditStudent)]
        public ActionResult CompanyEdit(int id, FormCollection formvalues)
        {
            Company company = accountRepository.GetCompany(id);
            if (company == null)
                return View("ShowMessage", "Company does now exists");
            if (TryUpdateModel(company, formvalues))
            {
                accountRepository.Save();
                return RedirectToAction("CompanyList");
            }
            ViewBag.Op = "Edit";
            
            return View("CompanyCreateEdit", company);
        }

        // **************************************
        // URL: /Account/CompanyList/
        // **************************************
        //[CustomAuthorize(Privileges = UserPrivileges.ListStudents)]
        public ActionResult CompanyList(int? page)
        {
            const int pageSize = 10;

            IQueryable<Company> companies = null;

            companies = accountRepository.FindAllCompanies();
               
            var paginatedCompanies = new PaginatedList<Company>(companies, page ?? 0, pageSize);

            return View(paginatedCompanies);
        }

        // **************************************
        // URL: /Account/CompanyDelete/
        // **************************************
        //[CustomAuthorize(Privileges = UserPrivileges.DeleteStudent)]
        public ActionResult CompanyDelete(int id)
        {
            Company company = accountRepository.GetCompany(id);
            accountRepository.DeleteCompany(company);
            User user = accountRepository.GetUserByID(id);
            accountRepository.DeleteUser(user);
            accountRepository.Save();
            return RedirectToAction("CompanyList");
        }




        #endregion

    }
}
